4.5 Die HAVING
-Anweisung
[9]SELECT abteilung_ID AS Abteilung, MIN(bruttolohn) AS MinLohn,
MAX(bruttolohn) AS MaxLohn, COUNT(*) AS Anzahl_der_Mitarbeiter
FROM tbl_mitarbeiter
GROUP BY abteilung_ID
Die Abfrage zeigt uns eine Auflistung der minimalen und maximalen Verdienste sowie die Anzahl der Angestellten jeder Abteilung.
Nun wollen wir aber einige Abteilungen von der Anzeige ausschließen und zwar alle diejenigen,
zu denen nur ein Mitarbeiter zählt.
Die Verwendung der WHERE
-Anweisung scheidet dabei aus, weil in ihr keine Aggregatfunktionen
erlaubt sind! Zum Einsatz kommt hier die HAVING
-Anweisung.
[7]SELECT abteilung_ID AS Abteilung, MIN(bruttolohn) AS MinLohn,
MAX(bruttolohn) AS MaxLohn, COUNT(*) AS Anzahl_der_Mitarbeiter
FROM tbl_mitarbeiter
GROUP BY abteilung_ID
HAVING COUNT(*) > 1
Mit dieser HAVING
-Anweisung wird die Anzeige auf diejenigen Abteilungen
beschränkt, die mehr als einen Mitarbeiter haben. In unserem Falle fallen damit die Abteilungen 02 und 11
heraus.
Es wäre möglich, den Aliasnamen (Anzahl_der_Mitarbeiter) in der HAVING
-Zeile zu verwenden.
Leider wird dies wiederum nicht von allen SQL-Dialekten unterstützt, so dass Sie es sich gar nicht erst angewöhnen
sollten.
Im Übrigen sei darauf hingewiesen, dass es egal ist, ob die Aggregat-Funktion
der HAVING
-Anweisung auch in der SELECT
-Zeile steht oder nicht.
HAVING
oder WHERE
Die Entscheidung zwischen WHERE
- und HAVING
-Anweisung fällt häufig schwer.
Mit der folgenden Anweisung wollen wir die Mitarbeiter aus der Berechnung ausschließen, deren Bruttolohn kleiner
gleich 1000 Euro ist. Dies ist natürlich weiterhin ein Fall für die WHERE
-Anweisung wobei diese vor dem
GROUP BY
stehen muss!
[2]SELECT abteilung_ID AS Abteilung, MIN(bruttolohn) AS MinLohn,
MAX(bruttolohn) AS MaxLohn, COUNT(*) AS Anzahl_der_Mitarbeiter
FROM tbl_mitarbeiter
WHERE bruttolohn > 1000
GROUP BY abteilung_ID
HAVING COUNT(*) > 1
Dieses Ergebnis könnte etwas verwundern - die oben gemachte Abfrage hatte doch ergeben, dass es in 7 Abteilungen mehr als einen Mitarbeiter gibt und auch der Maximallohn liegt in 6 Abteilungen über 1000 Euro. Um das Resultat zu verstehen muss man also wissen, wie die einzelnen Teile der Abfrage nacheinander abgearbeitet werden:
Die WHERE
-Bedingung wird vor dem Bilden der Gruppen ausgeführt und führt dazu, dass bestimmte
Datensätze nicht in die Berechnungen einfließen. Angezeigt werden dann nur die die Gruppen (hier Abteilungen),
welche der HAVING
-Bedingung entsprechen. Diese wird zuletzt angewandt, direkt bevor die
Ergebnisse ausgegeben werden – ohne jede Optimierung.
Das Ergebnis erklärt sich also wie folgt:
Durch die WHERE
-Bedingung werden alle Datensätze von Mitarbeitern ausgeschlossen, die weniger als oder
genau 1000 Euro verdienen. Nur über die übrigen Datensätze wird gruppiert und auch gezählt.
Durch das HAVING
bleiben dann nur zwei Abteilungen übrig - von denen wir nun wissen, dass hier mehr
als zwei Mitarbeiter mehr als 1000 Euro verdienen. Es ist für das Verständnis des Unterschieds zwischen
WHERE
und HAVING
sehr wichtig, dass Sie diese Argumentation nachvollziehen können.
Prüfen Sie deshalb diese Aussage, indem Sie nochmals in die Mitarbeitertabelle schauen.
Die WHERE
-Klausel legt Bedingungen für einzelne Datensätze fest,
im HAVING
führt man nur Bedingungen auf, die für Gruppen gelten. Benutzen Sie kein
HAVING
für Dinge, die in der WHERE
-Klausel stehen sollten.